home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.alaska-software.com
/
2014.06.ftp.alaska-software.com.tar
/
ftp.alaska-software.com
/
3pp
/
mxsetup.old
/
{app}
/
Regclass.prg
< prev
next >
Wrap
Text File
|
2001-08-08
|
25KB
|
904 lines
/*
Registry-Klassenbibliothek fⁿr Xbase++
=======================================================
Registry class for Xbase++
(C) Thomas Braun Softwareentwicklung
Hindenburgstr. 69
D-72336 Balingen
GERMANY
e-mail : braunt@compuserve.com
Homepage : http://www.software-braun.de
Feel free to use the source below in any project you
like as long as you keep the above copyright note.
The most current version of this class can be found on
my homepage.
Any comments and enhancements are always welcome.
If you have any questions regarding this source feel free
to contact me via e-mail.
---------------------------------------------------------------------------------------
CHANGE HISTORY (sorry german guys, only in english ;-) :
29.08.1999 Fixed a weird "duplicate variable declaration" error with Xbase++ SL2 1.20.204
21.08.1999 removed a left over "Return lSuccess" in xbpReg:DelKey()
Fixed bug in :Init() method with SET EXACT ON. Init is now saving
the current EXACT-state and restoring it when finished. (Thanks to
Ken Levitt for this)
18.04.1999 Added Section "CHANGE HISTORY"
New iVar cReadBinaryTypeAs
New ACCESS/ASSIGN ReadBinType
New Method ::ValueList() for retrieving a 2-dim array that contains all
value names - value pairs. (so now you can query if
a value already exists)
several minor bugfixes regarding the useage under WindowsNT
(thanks to Axel Zimelka for this one and Johan Droskie for some
other comments)
*/
#include "common.ch"
#include "dll.ch"
#include "regclass.ch"
#include "set.ch"
/*
Registry Klasse, verwaltet Informationen und stellt Zugriffsfunktionen fⁿr einen
bestimmten RegistryKey bereit. Dieser mu▀ in der Init-Funktion angegeben werden.
Die Manipulationsmethoden erlauben es dann, Werte und weitere Key┤s hinzu-
zufⁿgen / zu l÷schen / abzufragen usw.
=================================================================================
Registry class, contains information and accessfunctions for a single
registry key. The name of the key must be set with the init method.
The manipulation methods then allow to add/delete keys and values
*/
CLASS XbpReg
HIDDEN:
METHOD RegOpenKeyEx, RegCreateKeyEx, RegQueryInfoKey, RegCloseKey
METHOD RegEnumKeyEx, RegEnumValue
VAR nHKey // numerical handle from regclass.ch for the root key
VAR cKey // Name of Subkey to open
VAR nKeyHandle // Handle to currently open key
VAR lStatus // State of Key┤s (see comment in the init method)
VAR nCallSuccess // return value of all Reg...DLL functions
VAR nDllHandle // DLL handle
VAR xValue // general purpose iVar
VAR cClass
VAR nClass
VAR nSubKeys
VAR nMaxSubKeyLen
VAR nMaxClassLen
VAR nValues
VAR nMaxValueNameLen
VAR nMaxValueLen
VAR nSecurityDescriptor
VAR cLastWriteTime
VAR nLastWriteTime
VAR cReadBinaryTypeAs
EXPORTED:
METHOD Init, Create
METHOD NewKey, DelKey
METHOD GetValue, SetValue, DelValue
METHOD KeyList, MoveUp, MoveDown
METHOD ValueList
ACCESS ASSIGN METHOD Standard
ACCESS ASSIGN METHOD ReadBinType // get/set ::cReadBinaryTypeAs
ACCESS METHOD Status
ACCESS METHOD KeyName
ENDCLASS
/*
Init-Methode. Ermitteln, welcher Root-Key ben÷tigt wird und diesen in ::nHKey
eintragen.
Subkey ermitteln und diesen in ::cKey eintragen
Die Memberfunktion ::Status() gibt einen logischen Wert zurⁿck der angibt,
ob der Key bereits in der Registry angelegt ist (.T.) oder nicht (.F.)
Wird lCreate auf .T. (default = .F.) gesetzt und existiert der Key noch nicht,
so wird er neu angelegt. Anderenfalls mu▀ er mittels der Methode ::create()
erzeugt werden.
=======================================================================================
Init method. First determine the needed root key which is then stored in ::nHKey
Determine subkey name and store into ::cKey
The member function ::Status() returns a logical value that states if the key already
exists in the registry (.T.) or not (.F.)
If lCreate is set to .T. (default = .F.) and the key does not exist, it is
created in the init method.
Otherwise it has to be created via the :create() method.
*/
METHOD XbpReg:Init( cRegKey, lCreate, lReInit )
LOCAL nPos := 0
/*
Turning EXACT off, otherwise some string compares will fail...
======================
EXACT auf "OFF" schalten, weil sonst einige String-Vergleiche weiter
unten scheitern...
*/
LOCAL lSetExact := SET( _SET_EXACT , .F. )
DEFAULT cRegKey TO ""
DEFAULT lCreate TO .F.
DEFAULT lReInit TO .F.
::lStatus := .F.
::nDllHandle := 0
::cClass := ""
::nClass := 0
::nSubKeys := 0
::nMaxSubKeyLen := 0
::nMaxClassLen := 0
::nValues := 0
::nMaxValueNameLen := 0
::nMaxValueLen := 0
::nSecurityDescriptor := 0
::cLastWriteTime := ""
::nLastWriteTime := 0
// Keep setting when doing :MoveUp / :MoveDown
If ! lReInit
::cReadBinaryTypeAs := "A" // Read Binary data into an array
EndIF
If ! EMPTY( cRegKey )
If cRegKey = "\" // remove backslash
cRegKey := SUBSTR( cRegKey, 2 )
EndIF
nPos := AT( "\", cRegKey ) // det. name of subkey
DO CASE
CASE cRegKey = "HKEY_LOCAL_MACHINE"
::nHKey := HKEY_LOCAL_MACHINE
CASE cRegKey = "HKEY_CLASSES_ROOT"
::nHKey := HKEY_CLASSES_ROOT
CASE cRegKey = "HKEY_USERS"
::nHKey := HKEY_USERS
CASE cRegKey = "HKEY_CURRENT_USER"
::nHKey := HKEY_CURRENT_USER
OTHERWISE
::nHKey := HKEY_NO_KEY
ENDCASE
If ::nHKey # HKEY_NO_KEY // if root key exists
If nPos # 0
::cKey := SUBSTR( cRegKey, nPos + 1 )
Else
::cKey := ""
ENDIF
::RegOpenKeyEx( ::cKey ) // open key
If ::nCallSuccess = ERROR_SUCCESS
::lStatus := .T.
ELSE
If lCreate
::RegCreateKeyEx( ::cKey )
IF ::nCallSuccess = ERROR_SUCCESS
::lStatus := .T.
EndIF
EndIF
EndIF
::RegCloseKey()
EndIF
EndIF
SET( _SET_EXACT , lSetExact )
RETURN self
/*
Registry Key erzeugen, hat nur eine Bedeutung, wenn der Key noch nicht existiert
d.H. ::Status() == .F.
Create mu▀ nicht aufgerufen werden, wenn der Key existiert oder die init Methode
mit lCreate == .T. aufgerufen wurde.
===================================
Create registry key. Only works if the key does not exist (::Status() = .F.)
Create is not needed if the Key exists or you call the init method with
lCreate == .T.
*/
METHOD XbpReg:Create
If ::lStatus == .F. .AND. ::nHKey # HKEY_NO_KEY
::RegOpenKeyEx( ::cKey ) // open registry key
If ::nCallSuccess = ERROR_SUCCESS
::lStatus := .T.
ELSE
::RegCreateKeyEx( ::cKey )
IF ::nCallSuccess = ERROR_SUCCESS
::lStatus := .T.
EndIF
EndIF
::RegCloseKey() // close registry key
EndIF
RETURN self
/*
Registry Key ÷ffnen
================================
Open registry key
*/
METHOD XbpReg:RegOpenKeyEx( cSubKey )
LOCAL nNewKeyHandle := 0
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
If ::nhKey # HKEY_NO_KEY
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegOpenKeyExA", ::nhKey,;
cSubKey, 0, KEY_ALL_ACCESS , @nNewKeyHandle )
If ::nCallSuccess = ERROR_SUCCESS
::nKeyHandle := nNewKeyHandle
::RegQueryInfoKey()
EndIF
EndIF
RETURN ::nCallSuccess
/*
Registry-Schlⁿssel schlie▀en
=======================================
Close registry key
*/
METHOD XbpReg:RegCloseKey
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegCloseKey", ::nKeyHandle )
If ::nCallSuccess = ERROR_SUCCESS
::nKeyHandle := HKEY_NO_KEY
EndIF
If ::nDllHandle # 0
DllUnload( ::nDllHandle )
::nDllHandle := 0
EndIF
RETURN ::nCallSuccess
/*
Neuen Registry Key erzeugen
=============================================
Create new key
*/
METHOD XbpReg:RegCreateKeyEx( cSubKey )
LOCAL nNewKeyHandle := 0, nDisposition := 0
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegCreateKeyExA", ::nHKey,;
cSubKey, 0, "", REG_OPTION_NON_VOLATILE, ;
KEY_ALL_ACCESS , 0, @nNewKeyHandle, @nDisposition )
If ::nCallSuccess = ERROR_SUCCESS
::nKeyHandle := nNewKeyHandle
::RegQueryInfoKey()
::RegCloseKey()
EndIF
RETURN ::nCallSuccess
/*
Neuen Subkey unterhalb des existierenden anlegen
========================================================
Create subkey below existing key
*/
METHOD XbpReg:NewKey( cSubKey, lKeepOld )
LOCAL cOldKey := ::KeyName(), lSuccess
DEFAULT cSubKey TO ""
DEFAULT lKeepOld TO .T.
If ! EMPTY( cSubkey )
::Init( cOldKey + "\" + cSubKey, .T., .T. )
If ! ::lStatus
::Init( cOldKey,,.T. )
Else
lSuccess := .T.
If lKeepOld
::Init( cOldKey,,.T. )
EndIF
Endif
EndIF
RETURN lSuccess
/*
Subkey unterhalb des existierenden l÷schen
============================================================
Delete subkey (including all contained values and subkeys)
*/
METHOD XbpReg:DelKey( cSubKey )
LOCAL lRet := .F.
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::RegOpenKeyEx( ::cKey )
If ::nCallSuccess = ERROR_SUCCESS
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegDeleteKeyA", ::nKeyHandle,;
cSubKey )
lRet := ::nCallSuccess = ERROR_SUCCESS
ENDIF
::RegCloseKey()
RETURN lRet
/*
Informationen ⁿber Registry Key ermitteln und in den vorgesehenen iVar┤s
ablegen.
====================================================================================
Gather information about registry key
*/
METHOD XbpReg:RegQueryInfoKey
LOCAL lpClass := "", lpcbClass := 0, lpReserved := 0, lpcSubKeys := 0
LOCAL lpcbMaxSubKeyLen := 0, lpcbMaxClassLen := 0
LOCAL lpcValues := 0, lpcbMaxValueNameLen := 0, lpcbMaxValueLen := 0
LOCAL lpcbSecurityDescriptor := 0, lpftLastWriteTime := " "
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegQueryInfoKeyA", ::nKeyHandle,;
@lpClass,;
@lpcbClass,;
lpReserved,;
@lpcSubKeys,;
@lpcbMaxSubKeyLen,;
@lpcbMaxClassLen,;
@lpcValues,;
@lpcbMaxValueNameLen,;
@lpcbMaxValueLen,;
@lpcbSecurityDescriptor,;
@lpftLastWriteTime )
If ::nCallSuccess = ERROR_SUCCESS
::cClass := lpClass
::nClass := lpcbClass
::nSubKeys := lpcSubKeys
::nMaxSubKeyLen := lpcbMaxSubKeyLen
::nMaxClassLen := lpcbMaxClassLen
::nValues := lpcValues
::nMaxValueNameLen := lpcbMaxValueNameLen
::nMaxValueLen := lpcbMaxValueLen
// the following is only valid under WIN/NT
::nSecurityDescriptor := lpcbSecurityDescriptor
::cLastWriteTime := lpftLastWriteTime
::nLastWriteTime := Bin2U( SUBSTR( ::cLastWriteTime, 1, 4 ) ) +;
Bin2U( SUBSTR( ::cLastWriteTime, 5, 4 ) ) * 2^32
EndIF
RETURN ::nCallSuccess
/*
Subkeys aus der Registry enumerieren (AufzΣhlen)
Hilfsmethode, vorher mu▀ der Registry-Key mit ::RegOpenKeyEx ge÷ffnet
worden sein.
=================================================================================
Enumerate subkeys, key has to be opened before with ::RegOpenKeyEX
*/
METHOD xbpReg:RegEnumKeyEx( nIndex )
LOCAL cBuffer := SPACE( ::nMaxSubKeyLen + 1 )
LOCAL nBufLen := ::nMaxSubKeyLen + 1
LOCAL lpftLastWriteTime := " "
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegEnumKeyExA", ::nKeyHandle,;
nIndex, @cBuffer, @nBufLen, 0, 0, 0, @lpftLastWriteTime )
If ::nCallSuccess = ERROR_SUCCESS
::cLastWriteTime := lpftLastWriteTime
::nLastWriteTime := Bin2U( SUBSTR( ::cLastWriteTime, 1, 4 ) ) +;
Bin2U( SUBSTR( ::cLastWriteTime, 5, 4 ) ) * 2^32
EndIF
RETURN TRIM(cBuffer)
/*
Values aus der Registry enumerieren (AufzΣhlen)
Hilfsmethode, vorher mu▀ der Registry-Key mit ::RegOpenKeyEx ge÷ffnet
worden sein.
=================================================================================
Enumerate values, key has to be opened before with ::RegOpenKeyEx
*/
METHOD xbpReg:RegEnumValue( nIndex, lWithValue )
LOCAL cBuffer1 := SPACE( ::nMaxValueNameLen + 1 )
LOCAL nBufLen1 := ::nMaxValueNameLen + 1
LOCAL cBuffer2 := SPACE( ::nMaxValueLen + 1 )
LOCAL nBufLen2 := ::nMaxValueLen + 1
LOCAL nType := 0
LOCAL lpftLastWriteTime := " "
LOCAL aRet := {}
LOCAL bError
DEFAULT lWithValue TO .T.
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::xValue := NIL
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegEnumValueA", ::nKeyHandle,;
nIndex, @cBuffer1, @nBufLen1, 0, @nType, @cBuffer2, @nBufLen2 )
If ::nCallSuccess = ERROR_SUCCESS
AADD( aRet, TRIM(SUBSTR(cBuffer1,1,nBufLen1)) )
If lWithValue
DO CASE
CASE nType == REG_SZ
::xValue := SUBSTR( cBuffer2, 1, nBufLen2-1 )
CASE nType == REG_DWORD
::xValue := BIN2L( cBuffer2 )
CASE nType == REG_BINARY
DO CASE
CASE ::cReadBinaryTypeAs = "A"
::xValue := Bin2Var( cBuffer2 )
CASE ::cReadBinaryTypeAs = "C"
::xValue := cBuffer2
CASE ::cReadBinaryTypeAs = "N"
::xValue := BIN2L( cBuffer2 )
EndCASE
ENDCASE
EndIF
AADD( aRet, ::xValue )
ENDIF
RETURN aRet
/*
Wert aus Registry-Schlⁿssel auslesen
======================================================
Get a named value
*/
METHOD XbpReg:GetValue( cName )
LOCAL xRet := SPACE(::nMaxValueLen), nRet := ::nMaxValueLen
LOCAL nType := 0
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::xValue := NIL
::RegOpenKeyEx( ::cKey )
If ::nCallSuccess = ERROR_SUCCESS
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegQueryValueExA", ::nKeyHandle,;
@cName, 0, @nType , @xRet, @nRet )
If ::nCallSuccess = ERROR_SUCCESS
DO CASE
CASE nType == REG_SZ
::xValue := SUBSTR( xRet, 1, nRet-1 )
CASE nType == REG_DWORD
::xValue := BIN2L( xRet )
CASE nType == REG_BINARY
DO CASE
CASE ::cReadBinaryTypeAs = "A"
::xValue := Bin2Var( xRet )
CASE ::cReadBinaryTypeAs = "C"
::xValue := xRet
CASE ::cReadBinaryTypeAs = "N"
::xValue := BIN2L( xRet )
EndCASE
ENDCASE
Endif
ENDIF
::RegCloseKey()
RETURN ::xValue
/*
Wert in Registry-Value ablegen, bzw. Value neu erzeugen
===================================================================
Write/create a named value
*/
METHOD XbpReg:SetValue( cName, xValue )
LOCAL nLen := 0, nType := REG_NONE
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
DO CASE
CASE VALTYPE( xValue ) = "C"
nLen := LEN(xValue) + 1
nType := REG_SZ
CASE VALTYPE( xValue ) = "N"
nLen := 4
xValue := L2BIN( xValue )
nType := REG_DWORD
CASE VALTYPE( xValue ) = "A"
xValue := Var2Bin( xValue )
nLen := LEN( xValue )
nType := REG_BINARY
ENDCASE
::RegOpenKeyEx( ::cKey )
If ::nCallSuccess = ERROR_SUCCESS
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegSetValueExA", ::nKeyHandle,;
@cName, 0, nType , @xValue, nLen )
If ::nCallSuccess = ERROR_SUCCESS
EndIF
ENDIF
::RegCloseKey()
RETURN ::nCallSuccess
/*
Value l÷schen
========================================
Delete value
*/
METHOD XbpReg:DelValue( cName )
LOCAL lRet := .F.
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::RegOpenKeyEx( ::cKey )
If ::nCallSuccess = ERROR_SUCCESS
::nCallSuccess := DllCall( ::nDllHandle, DLL_STDCALL, "RegDeleteValueA", ::nKeyHandle,;
@cName )
lRet := ::nCallSuccess = ERROR_SUCCESS
ENDIF
::RegCloseKey()
RETURN lRet
/*
"Standard"-Wert des Registry-Key┤s abfragen oder setzen, als Beispiel siehe
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\TimeZones
==================================================================================
Get/Set "standard" value of the registry key for example see
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\TimeZones
*/
METHOD XbpReg:Standard( xValue )
If xValue # NIL
::SetValue( "", xValue )
Endif
RETURN ::GetValue( "" )
/*
ACCESS/ASSIGN stellt den xBase++ Datentyp ein, der beim Lesen von binären Daten
aus der Registry verwendet werden soll. Standard ist "A" = Array, d.H.
Daten mit dem Attribut REG_BINARY werden mit BIN2VAR in ein Array umgewandelt.
(!!! Arrays werden generell mit VAR2BIN gespeichert !!!)
==================================================================================
ACCESS/ASSIGN to get/set the Xbase++ datatype that should be used when reading
binary data from the registry. The standard value is "A" so that data with the
REG_BINARY type attribute gets transferred into an array via BIN2VAR.
(Generally arrays are stored into the registry via VAR2BIN when using ::SetValue()
*/
METHOD XbpReg:ReadBinType( xValue )
LOCAL cType := ::cReadBinaryTypeAs
If !empty(xValue)
If VALTYPE(xValue) = "C"
::cReadBinaryTypeAs := xValue
Endif
Endif
RETURN cType
/*
Status des Objekts abfragen
================================================
Get object status
*/
METHOD XbpReg:Status
RETURN ::lStatus
/*
VollstΣndigen Namen des Registry-Keys zurⁿckliefern
====================================================================
Return complete registry key "path"
*/
METHOD XbpReg:KeyName
LOCAL cRet := "\"
DO CASE
CASE ::nHKey = HKEY_LOCAL_MACHINE
cRet += "HKEY_LOCAL_MACHINE"
CASE ::nHKey = HKEY_CLASSES_ROOT
cRet += "HKEY_CLASSES_ROOT"
CASE ::nHKey = HKEY_USERS
cRet += "HKEY_USERS"
CASE ::nHKey = HKEY_CURRENT_USER
cRet += "HKEY_CURRENT_USER"
ENDCASE
cRet += IIF( ! EMPTY(::cKey), "\" + ::cKey, "" )
RETURN cRet
/*
Liste aller Subkeys als Array zurⁿckgeben
Verwendet ::RegEnumKeyEx()
==================================================
List all subkeys (returns an array)
Uses ::RegEnumKeyEx()
*/
METHOD XbpReg:KeyList
LOCAL nIndex, aRet := {}, cEnumKey
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::RegOpenKeyEx( ::cKey ) // Key ÷ffnen, Fehlercode steht in ::nCallSuccess
If ::nCallSuccess = ERROR_SUCCESS
nIndex := ::nSubKeys
DO WHILE nIndex >= 0
If ! EMPTY( cEnumKey := ::RegEnumKeyEx( nIndex ) )
AADD( aRet, cEnumKey )
EndIF
nIndex--
EndDO
ENDIF
::RegCloseKey()
If LEN( aRet ) # 0
aRet := ASORT( aRet,,, {|c1,c2| UPPER(c1) < UPPER(c2) } )
EndIF
RETURN aRet
/*
Liste aller Values des Keys als 2-dimensionales Array zurⁿckgeben
Wird lWithValues auf .F. gesetzt ist das zweite Arrayelement jeweils NIL,
es werden also nur die ValueNamen, nit jedoch der Wert selbst ermittelt.
Vorgabewert ist .T. = Werte ermitteln
Verwendet ::RegEnumValue()
==================================================
List all values (returns an 2-dimensional array)
Set lWithValues to .F. if you only need the value names, not the value itself
Default is .T.
Uses ::RegEnumValue()
*/
METHOD XbpReg:ValueList( lWithValues )
LOCAL nIndex, aRet := {}, aEnumVal
DEFAULT lWithValues TO .T.
::nCallSuccess := 1 // 1 = no success; 0 = success
If ::nDllHandle = 0
::nDllHandle := DllLoad( "ADVAPI32.DLL" )
EndIF
::RegOpenKeyEx( ::cKey ) // Key ÷ffnen, Fehlercode steht in ::nCallSuccess
If ::nCallSuccess = ERROR_SUCCESS
nIndex := ::nValues
If nIndex # 0
::RegEnumValue( 0 )
EndIF
DO WHILE nIndex >= 0
If LEN( aEnumVal := ::RegEnumValue( nIndex, lWithValues ) ) # 0
AADD( aRet, aEnumVal )
EndIF
nIndex--
EndDO
ENDIF
::RegCloseKey()
If LEN( aRet ) # 0
aRet := ASORT( aRet,,, {|c1,c2| UPPER(c1[1]) < UPPER(c2[1]) } )
EndIF
RETURN aRet
/*
Eine Ebene h÷her in der Schlⁿsselhierarchie
(Σhnlich dem DOS-Kommando CD..)
=====================================================
Move one level up in the key hierarchy
(similar to the dos command CD..)
*/
METHOD xbpReg:MoveUp
LOCAL cNewKey, nPos, lSuccess := .F.
nPos := RAT( "\", ::KeyName() )
If nPos > 1
cNewKey := LEFT( ::KeyName, nPos-1)
::Init( cNewKey,,.T. )
lSuccess := ::lStatus
EndIF
RETURN lSuccess
/*
Eine Ebene tiefer in der Schlⁿsselhierarchie
===========================================================
Move down one level
*/
METHOD xbpReg:MoveDown( cSubkey )
LOCAL cOldKey := ::KeyName(), lSuccess := .F.
DEFAULT cSubKey TO ""
If ! EMPTY( cSubkey )
::Init( cOldKey + "\" + cSubKey,,.T. )
If ! ::lStatus
::Init( cOldKey,,.T. )
Else
lSuccess := .T.
Endif
EndIF
RETURN lSuccess